"""
阿里云OSS上传工具
"""
import os
import uuid
from datetime import datetime
import oss2
from fastapi import UploadFile, HTTPException


# OSS配置
OSS_ACCESS_KEY_ID = "LTAI5tSrNgD84u5ncizQxT8W"
OSS_ACCESS_KEY_SECRET = "7JdiVIm8GgcCx98plQkrGHmNgnD3tU"
OSS_ENDPOINT = "oss-cn-hangzhou.aliyuncs.com"
OSS_BUCKET_NAME = "test-wins"
OSS_FOLDER = "WinsImages"

# 允许上传的图片格式
ALLOWED_EXTENSIONS = {'.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp'}
# 最大文件大小 (10MB)
MAX_FILE_SIZE = 10 * 1024 * 1024


def get_file_extension(filename: str) -> str:
    """获取文件扩展名"""
    return os.path.splitext(filename)[1].lower()


def generate_unique_filename(original_filename: str) -> str:
    """生成唯一的文件名"""
    ext = get_file_extension(original_filename)
    timestamp = datetime.now().strftime('%Y%m%d%H%M%S')
    unique_id = uuid.uuid4().hex[:8]
    return f"{timestamp}_{unique_id}{ext}"


def validate_image_file(file: UploadFile) -> None:
    """验证图片文件"""
    # 检查文件扩展名
    ext = get_file_extension(file.filename)
    if ext not in ALLOWED_EXTENSIONS:
        raise HTTPException(
            status_code=400,
            detail=f"不支持的文件格式。允许的格式: {', '.join(ALLOWED_EXTENSIONS)}"
        )
    
    # 检查文件大小
    file.file.seek(0, 2)  # 移动到文件末尾
    file_size = file.file.tell()
    file.file.seek(0)  # 移动回文件开头
    
    if file_size > MAX_FILE_SIZE:
        raise HTTPException(
            status_code=400,
            detail=f"文件大小超过限制。最大允许: {MAX_FILE_SIZE / 1024 / 1024}MB"
        )


async def upload_image_to_oss(file: UploadFile) -> str:
    """
    上传图片到阿里云OSS
    
    Args:
        file: FastAPI UploadFile对象
        
    Returns:
        str: 图片的完整URL
        
    Raises:
        HTTPException: 上传失败时抛出异常
    """
    try:
        # 验证文件
        validate_image_file(file)
        
        # 生成唯一文件名
        unique_filename = generate_unique_filename(file.filename)
        
        # OSS对象路径
        object_name = f"{OSS_FOLDER}/{unique_filename}"
        
        # 初始化OSS Auth和Bucket
        auth = oss2.Auth(OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET)
        bucket = oss2.Bucket(auth, OSS_ENDPOINT, OSS_BUCKET_NAME)
        
        # 读取文件内容
        file_content = await file.read()
        
        # 上传到OSS
        result = bucket.put_object(object_name, file_content)
        
        if result.status != 200:
            raise HTTPException(
                status_code=500,
                detail=f"OSS上传失败: {result.status}"
            )
        
        # 构建并返回图片URL
        image_url = f"https://{OSS_BUCKET_NAME}.{OSS_ENDPOINT}/{object_name}"
        return image_url
        
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail=f"上传图片失败: {str(e)}"
        )
    finally:
        # 确保文件指针回到开头
        await file.seek(0)


def delete_image_from_oss(image_url: str) -> bool:
    """
    从OSS删除图片
    
    Args:
        image_url: 图片完整URL
        
    Returns:
        bool: 删除是否成功
    """
    try:
        # 从URL提取object_name
        # URL格式: https://test-wins.oss-cn-hangzhou.aliyuncs.com/WinsImages/xxx.jpg
        if OSS_BUCKET_NAME not in image_url:
            return False
            
        parts = image_url.split(f"{OSS_BUCKET_NAME}.{OSS_ENDPOINT}/")
        if len(parts) != 2:
            return False
            
        object_name = parts[1]
        
        # 初始化OSS
        auth = oss2.Auth(OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET)
        bucket = oss2.Bucket(auth, OSS_ENDPOINT, OSS_BUCKET_NAME)
        
        # 删除对象
        bucket.delete_object(object_name)
        return True
        
    except Exception as e:
        print(f"删除OSS图片失败: {str(e)}")
        return False

